<template>
    <div class="main">
        <el-form :model="loginUser" :rules="rules" label-width="100px" ref="loginForm">
            <div>
                <h2 style="text-align: center;color: #333;">思泰隆-健身房课程预约系统(STL-gym)</h2>
            </div>

            <el-form-item label="用户名：" prop="username">
                <el-input v-model="loginUser.username" placeholder="请输入用户名" autocomplete="off" />
            </el-form-item>

            <el-form-item label="密码：" prop="password">
                <el-input type="password" v-model="loginUser.password" placeholder="请输入密码" show-password />
            </el-form-item>

            <el-form-item label="">
                <!-- login的参数loginForm，即el-form组件中定义的ref属性值，是一个表单实例对象。当然，此对象也可在js中可直接访问，无须通过此种方式传参 -->
                <el-button type="primary" @click="login(loginForm)">
                    <el-icon>
                        <Check />
                    </el-icon>&nbsp;登录
                </el-button>
                <el-button type="primary">
                    <el-icon>
                        <CircleClose />
                    </el-icon>&nbsp;重置
                </el-button>
            </el-form-item>

        </el-form>
    </div>
</template>

<script setup>
import { reactive, toRaw } from "vue";
//导入api函数
import { findByUsername as apiFindByUsername, login as apiLogin } from "@/api/UserApi";
// 
import { save as saveToken } from "@/util/token";

//导入路由派发器
import { useRouter } from "vue-router";
//获取路由派发器
const router = useRouter();

//表单模型数据
const loginUser = reactive({
    username: "13312341234",
    password: "123_abc_DEF"
});

//表单校验规则，此规则对象无须响应式。注意：首先在el-form组件上指定:rules属性，然后此规则中的key要和el-form-item中prop指定的属性值匹配。
const rules = {
    username: [{
        required: true, message: "用户名不可为空", trigger: "blur"
    }, {
        min: 6, max: 12, message: "用户名长度必须是6~12位之间", trigger: "blur"
    }, {
        validator: checkUsername, trigger: "blur"
    }],
    password: [{
        required: true, message: "密码不可为空", trigger: "blur"
    }, {
        min: 6, max: 12, message: "密码长度必须是6~12位之间", trigger: "blur"
    }, {
        validator: checkPassword, trigger: "blur"
    }]
};

//用户名自定义校验规则
async function checkUsername(rule, value, cb) {
    //console.log(rule, value, cb);

    //向后台数据库查询
    let result = await apiFindByUsername(value);

    if (result) {
        cb();
    } else {
        cb(new Error("用户名不存在"));
    }
}

//密码自定义校验规则
function checkPassword(rule, value, cb) {
    //至少拥有一个大写字母、小写字母、一个数字，长度为6~32位
    let regex = /^(?=.*[A-Z]+)(?=.*[a-z]+)(?=.*[0-9]+).{6,32}$/;

    if (value.match(regex)) {
        cb();
    } else {
        cb(new Error("密码中至少应包含一个大写字母，一个小写字母，一个数字"));
    }
}

//定义一个表单对象，此对象在表单el-form组件中，通过ref属性来指定，此对象无须响应式
let loginForm;

//点击登录按钮时调用此函数。此参数form即formRef，即便不传递，也可以直接使用formRef
function login(form) {
    //console.log(form === formRef);

    //打印响应式对象的值
    //console.log(formModel);

    loginForm.validate(async (valid, invalidFields) => {
        if (valid) {//已通过校验
            //由于formModel是响应是对象，是Proxy类型的实例，而向后台传递数据里，
            //只需要最基本的数据即可，所以此处需要转换为原始数据模型
            let user = toRaw(loginUser);

            let result = await apiLogin(user);

            if (result.success) {
                saveToken(resp.token);
                router.push("/main");//路由到"/main"
            } else {
                console.log("登录失败");
            }
        }
    });

    //此函数，用以清空所有表单字段
    //formRef.resetFields();
}
</script>


<style scoped>
.main {
    background-color: cornflowerblue;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
}

form {
    width: 550px;
    height: 350px;
    background-color: white;
}

form>div:not(:first-child) {
    padding-right: 20px;
}
</style>